package io.github.biezhi.elves.thread;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;

import io.github.biezhi.elves.common.Constants;
import io.github.biezhi.elves.ok.http.FastHttpClient;
import io.github.biezhi.elves.property.CityProperty;
import io.github.biezhi.elves.qcc.model.CompBasic;
import io.github.biezhi.elves.qcc.model.CompQccCrawl;
import io.github.biezhi.elves.qcc.model.CompUniscid;
import io.github.biezhi.elves.service.QccRealTimeService;
import io.github.biezhi.elves.service.QccUniscidService;
import io.github.biezhi.elves.spider.QccResolve;
import io.github.biezhi.elves.utils.StringUtils;

@Component
public class QccUniscidRunnable implements Runnable {
	
	private String qccCookie;
	private List<CompBasic> compBasicList;
	
	
	public QccUniscidRunnable() {
		super();
	}
	public QccUniscidRunnable(String qccCookie,List<CompBasic> compBasicList) {
		this.qccCookie = qccCookie;
		this.compBasicList = compBasicList;
	}

	@Autowired
	private QccUniscidService qccUniscidServiceBean;
	private static QccUniscidService qccUniscidService;
	
	@Bean
	public QccUniscidService getQccUniscidServiceBean(){
		if(qccUniscidServiceBean!=null){
			qccUniscidService = qccUniscidServiceBean;
			return qccUniscidService;
		}
		return null;
	}
	
	private String url = "https://www.qcc.com/";
	
	
	@Override
	public void run() {
			for (CompBasic compBasic : compBasicList) {
				CompUniscid compUniscid = new CompUniscid();
				//获取企业名称
				String compName = compBasic.getCompName();
				//获取企业详细url
				String htmlContentByCompName = getHtmlContentByCompName(compName);
				String compDetailUrl = getCompDetailUrl(htmlContentByCompName, compName);
				
				//获取企查查信息id
				String qccId = "";
				//获取企业详情html
				String compDetailHtml = "";
				//获取企业信用代码
				String uniscid = "";
				//地址
				String dom = "";
				//经营范围
				String opscope = "";
				//法人
				String name = "";
				//注册资金
				String regcap = "";
				//电话
				String tel = "";
				//企业类型
				String compType = "";
				//经营状态(登记状态)
				String status = "";
				//登记机关
				String regorg = "";
				//成立日期
				String estdate = "";
				//行业		
				String industry = "";
				
				if (compDetailUrl != "") {
					qccId = compDetailUrl.substring(compDetailUrl.indexOf("_")+1, compDetailUrl.indexOf("."));
					compDetailHtml = getHtmlContentByCompDetailUrl(compDetailUrl);
//					System.out.println(compDetailUrl);
					Document doc = Jsoup.parse(compDetailHtml);
//					System.out.println(doc.html());
//					System.out.println(doc.select("#base_div"));
//					System.out.println(doc.select("#base_div table.ntable"));
					if (doc.select("#base_div table.ntable").size()==0) {
						continue;
					}
					String tableText= doc.select("#base_div table.ntable").get(0).text();
					//便于正则匹配
					tableText = tableText + " ";
					
//					String rgex1 = "统一社会信用代码 (.*?)[\\s]";
//					uniscid = getSubUtilSimple(tableText,rgex1);
					//地址
					String rgex2 = "地址 (.*?)[\\s]";
					String rgex21 = "住所 (.*?)[\\s]";
					dom = getSubUtilSimple(tableText,rgex2);
					if (dom!= null && "".equals(dom.trim())) {
						dom = getSubUtilSimple(tableText,rgex21);
					}
					
					//经营范围
					String rgex3 = "宗旨和业务范围 (.*?)[\\s]";
					String rgex31 = "业务范围 (.*?)[\\s]";
//					String rgex3 = "经营范围 (.*?)[\\s]";
					opscope = getSubUtilSimple(tableText,rgex3);
					if (opscope!= null && "".equals(opscope.trim())) {
						opscope = getSubUtilSimple(tableText,rgex21);
					}
					
					//法定代表人
//					name = doc.select("#base_div table.ntable").get(0).select("a.bname > h2.seo.font-20").text();
					
					//开办资金
//					String rgex4 = "开办资金 (.*?)[\\s]";
//					String rgex4 = "注册资本 (.*?)[\\s]";
//					regcap = getSubUtilSimple(tableText,rgex4);
					
					
					//企业类型
//					String rgex5 = "企业类型 (.*?)[\\s]";
//					compType = getSubUtilSimple(tableText,rgex5);
					
					//经营状态(登记状态)
//					String rgex6 = "登记状态 (.*?)[\\s]";
//					status = getSubUtilSimple(tableText,rgex6);
					
					//登记机关
//					String rgex7 = "登记机关 (.*?)[\\s]";
//					regorg = getSubUtilSimple(tableText,rgex7);
					
					//成立日期
//					String rgex8 = "成立日期 (.*?)[\\s]";
//					estdate = getSubUtilSimple(tableText,rgex8);
					
					//行业
					String rgex9 = "所属行业 (.*?)[\\s]";
					industry = getSubUtilSimple(tableText,rgex9);
					
//					try {
//						//电话
//						tel = doc.select("div#company-top span.cvlu").get(0).text();
//					} catch (Exception e) {
//						e.printStackTrace();
//					}
				}
				
//				compQccCrawl.setCompId(compId);
//				compQccCrawl.setPripid(pripid);
				compUniscid.setCompName(compName);
				compUniscid.setUniscid(uniscid);
				compUniscid.setDom(dom);
				compUniscid.setName(name);
				compUniscid.setOpscope(opscope);
				compUniscid.setRegcap(regcap);
				compUniscid.setTel(tel);
				compUniscid.setCompType(compType);
				compUniscid.setStatus(status);
				compUniscid.setRegorg(regorg);
				compUniscid.setEstdate(estdate);
				compUniscid.setIndustry(industry);
				
				System.out.println(compUniscid);
				
				//将compQccCrawl插入到数据库
				qccUniscidService.insertSpiderData(compUniscid);
				//将表字段更新为已爬取
				qccUniscidService.updateSpiderState(compName);
			}
	}
	
	String proxyIp = Constants.PROXY_IP;
	int proxyPort = Constants.PROXY_PORT;
	//通过get请求获取网页内容
	private String getHtmlContentByCompName(String compName) {
		String result = "";
		sleepTime(10000L);
		try {
			io.github.biezhi.elves.ok.http.Response okHttpResponse;
//			Proxy proxy = new Proxy(Proxy.Type.HTTP,new InetSocketAddress(Constants.PROXY_IP, Constants.PROXY_PORT));
			okHttpResponse = FastHttpClient
					.newBuilder()
//					.proxy(proxy)
					.build()
					.get()
					.addHeader("cookie", qccCookie)
					.url(url+"search?key="+compName)
					.build()
					.execute();
			System.out.println(url+"search?key="+compName+"qccCookie:"+qccCookie);
			result = okHttpResponse.string();
//			System.out.println(result);
			if (result.contains("<script>window.location.href='https://www.qcc.com/")
					|| result.contains("user_login_normal")) {
				System.err.println("操作过于频繁，休眠30s！" + Thread.currentThread().getName()+"========>"+qccCookie);
				sleepTime(30000L);
//				resetProxyIp();
				result = getHtmlContentByCompName(compName);
			}
			if(!StringUtils.isNullOrEmpty(result)){
				return result;
			}
		} catch (SocketTimeoutException e) {
			System.err.println("===连接超时，重新调用getHtmlContentByCompName(compName)方法===");
			sleepTime(10000L);
//			resetProxyIp();
			getHtmlContentByCompName(compName);
		} catch (Exception e) {
			e.printStackTrace();
			System.err.println("===其他异常，重新调用getHtmlContentByCompName(compName)方法===");
			sleepTime(10000L);
//			resetProxyIp();
			getHtmlContentByCompName(compName);
		}
		return result;
	}
	
	//通过get请求和公司详情页面的url获取网页内容
	private String getHtmlContentByCompDetailUrl(String compDetailUrl) {
		String result = "";
		try {
			sleepTime(10000L);
			io.github.biezhi.elves.ok.http.Response okHttpResponse;
//			Proxy proxy = new Proxy(Proxy.Type.HTTP,new InetSocketAddress(Constants.PROXY_IP, Constants.PROXY_PORT));
			okHttpResponse = FastHttpClient
					.newBuilder()
//					.proxy(proxy)
					.build()
					.get()
					.addHeader("cookie", qccCookie)
					.url(url+compDetailUrl+"#base")
					.build()
					.execute();
			
			result = okHttpResponse.string();
			if (result.contains("<script>window.location.href='https://www.qcc.com/")
					|| result.contains("user_login_normal")) {
				System.err.println("操作过于频繁，休眠30s！" + Thread.currentThread().getName()+"========>"+qccCookie);
				sleepTime(30000L);
//				resetProxyIp();
				result = getHtmlContentByCompDetailUrl(compDetailUrl);
			}
			if(!StringUtils.isNullOrEmpty(result)){
				return result;
			}
		} catch (SocketTimeoutException e) {
			System.err.println("===连接超时，重新调用getHtmlContentByCompDetailUrl(compDetailUrl)方法===");
			sleepTime(10000L);
//			resetProxyIp();
			getHtmlContentByCompDetailUrl(compDetailUrl);
		} catch (Exception e) {
			e.printStackTrace();
			System.err.println("===其他异常，重新调用getHtmlContentByCompDetailUrl(compDetailUrl)方法===");
			sleepTime(10000L);
//			resetProxyIp();
			getHtmlContentByCompDetailUrl(compDetailUrl);
		}
		return result;
	}
	
	//通过get请求和参数(企业图谱,投资族谱,关联图谱,股权结构图对应的参数)和keyNo获取json数据
	private String getHtmlContentByParamAndKeyNo(String param,String keyNo) {
		String result = "";
		String visitUrl = url+param+"?keyNo="+keyNo;
		sleepTime(10000L);
		try {
			io.github.biezhi.elves.ok.http.Response okHttpResponse;
//			Proxy proxy = new Proxy(Proxy.Type.HTTP,new InetSocketAddress(Constants.PROXY_IP, Constants.PROXY_PORT));
			okHttpResponse = FastHttpClient
					.newBuilder()
//					.proxy(proxy)
					.build()
					.get()
					.addHeader("cookie", qccCookie)
					.url(visitUrl)
					.build()
					.execute();
			
			result = okHttpResponse.string();
//			System.out.println(result);
			if (result.contains("<script>window.location.href='https://www.qcc.com/")
					|| result.contains("user_login_normal")) {
				System.err.println("操作过于频繁，休眠30s！" + Thread.currentThread().getName()+"========>"+qccCookie);
				sleepTime(30000L);
//				resetProxyIp();
				result = getHtmlContentByParamAndKeyNo(param,keyNo);
			}
			if(!StringUtils.isNullOrEmpty(result)){
				return result;
			}
		} catch (SocketTimeoutException e) {
			System.err.println("===连接超时，重新调用getHtmlContentByParamAndKeyNo(param,keyNo)方法===");
			sleepTime(10000L);
//			resetProxyIp();
			getHtmlContentByParamAndKeyNo(param,keyNo);
		} catch (Exception e) {
			e.printStackTrace();
			System.err.println("===其他异常，重新调用getHtmlContentByParamAndKeyNo(param,keyNo)方法===");
			sleepTime(10000L);
//			resetProxyIp();
			getHtmlContentByParamAndKeyNo(param,keyNo);
		}
		return result;
	}
	//休眠
	private void sleepTime(Long sleepTime) {
		try {
			Thread.sleep(sleepTime);
			System.err.println("休眠" + sleepTime + "毫秒后，往下执行");
		} catch (Exception e){}
	}
	
	private void resetProxyIp() {
		try{
			Map<String,Object> proxyIpMap = StringUtils.getHttpProxyIp(1);
			String proxyJson = JSONObject.toJSONString(proxyIpMap);
			System.out.println(proxyJson);
			proxyIp = StringUtils.getValueForKey("proxyHost", proxyIpMap);
			proxyPort = StringUtils.getIntValueForKey("proxyPort", proxyIpMap);
			
			System.out.println("代理ip{{}}==>" + proxyIp + "，代理端口{{}}==>" + proxyPort);
		} catch (Exception e) {
			System.err.println("获取第三方代理ip接口异常{{}}==>" + StringUtils.getErrorInfoFromException(e));
		}
	}

	/**
	 * 获取公司详情页面的url
	 * @param result 通过getHtmlContentByCompName爬取出来的的页面
	 * @return 公司详情页面的url
	 */
	public String getCompDetailUrl(String result,String compName){
		Document doc = Jsoup.parse(result);
		Elements allAElements = doc.select("a.ma_h1");
		ListIterator<Element> htmlAResultIter = allAElements.listIterator();
		while (htmlAResultIter.hasNext()) {
			Element element = (Element) htmlAResultIter.next();
			String text = element.text();
			//如果该内容等于compName,表明需要的就是这家公司，获取该a标签下的href
			if (text.equals(compName) || text.equals(compName.replace("（", "(").replace("）", ")"))) {
				String compDetailUrl = element.attr("href");
				return compDetailUrl;
			}
		}
		return "";
	}
	
	public static void main(String[] args) {
		QccUniscidRunnable qccUniscidRunnable = new QccUniscidRunnable();
		String xmlString = qccUniscidRunnable.getXmlString();
		Document doc = Jsoup.parse(xmlString);
		//统一社会信用代码
		/*String unifiedSocialCreditCode= doc.select("table.ntable").get(0).text();
		String rgex = "统一社会信用代码 (.*?)[\\s]";
		unifiedSocialCreditCode = qccUniscidRunnable.getSubUtilSimple(unifiedSocialCreditCode,rgex);
		System.out.println(unifiedSocialCreditCode);*/
		
		//统一社会信用代码
		String tableText= doc.select("#base_div table.ntable").get(0).text();
		tableText = tableText + " ";
		System.out.println(tableText);
		String rgex1 = "统一社会信用代码 (.*?)[\\s]";
		String uniscid = qccUniscidRunnable.getSubUtilSimple(tableText,rgex1);
		System.out.println(uniscid);
		//地址
		String rgex2 = "地址 (.*?)[\\s]";
		String dom = qccUniscidRunnable.getSubUtilSimple(tableText,rgex2);
		System.out.println(dom);
		
		//经营范围
//		String rgex3 = "宗旨和业务范围 (.*?)[\\s]";
		String rgex3 = "经营范围 (.*?)[\\s]";
		String opscope = qccUniscidRunnable.getSubUtilSimple(tableText,rgex3);
		System.out.println(opscope);
		
		//法定代表人
		String name = doc.select("#base_div table.ntable").get(0).select("a.bname > h2.seo.font-20").text();
		System.out.println(name);
		
		//开办资金
//		String rgex4 = "开办资金 (.*?)[\\s]";
		String rgex4 = "注册资本 (.*?)[\\s]";
		String regcap = qccUniscidRunnable.getSubUtilSimple(tableText,rgex4);
		System.out.println(regcap);
		
		//电话
		String tel = doc.select("div#company-top span.cvlu").get(0).text();
		System.out.println(tel);
		
		//企业类型
		String rgex5 = "企业类型 (.*?)[\\s]";
		String compType = qccUniscidRunnable.getSubUtilSimple(tableText,rgex5);
		System.out.println(compType);
		
		//经营状态(登记状态)
		String rgex6 = "登记状态 (.*?)[\\s]";
		String status = qccUniscidRunnable.getSubUtilSimple(tableText,rgex6);
		System.out.println(status);
		
		//登记机关
		String rgex7 = "登记机关 (.*?)[\\s]";
		String regorg = qccUniscidRunnable.getSubUtilSimple(tableText,rgex7);
		System.out.println(regorg);
		
		//成立日期
		String rgex8 = "成立日期 (.*?)[\\s]";
		String estdate = qccUniscidRunnable.getSubUtilSimple(tableText,rgex8);
		System.out.println(estdate);
		
		//行业
		String rgex9 = "所属行业 (.*?)[\\s]";
		String industry = qccUniscidRunnable.getSubUtilSimple(tableText,rgex9);
		System.out.println(industry);
		
		
	}
	
	public static String unicodeToUtf8(String unicodeStr){
		try {
			byte[] utf8  = unicodeStr.getBytes("UTF-8");
			String utf8Str = new String(utf8,"UTF-8");
			return utf8Str;
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	
public static String unicodeToString(String str) {
 
	Pattern pattern = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");
	Matcher matcher = pattern.matcher(str);
	char ch;
	while (matcher.find()) {
		//group 6728
		String group = matcher.group(2);
		//ch:'木' 26408
		ch = (char) Integer.parseInt(group, 16);
		//group1 \u6728
		String group1 = matcher.group(1);
		str = str.replace(group1, ch + "");
	}
	return str;
}

	
	//读取文本为字符串
	public String getXmlString() {
		String xmlString;
		char[] strBuffer = null;
		int flen = 0;
		File xmlfile = new File("D:\\qccHtml.html");
		try {
		FileInputStream input = new FileInputStream(xmlfile);
		InputStreamReader in=new InputStreamReader(input,"GBK");//字节流字符流转化的桥梁
		flen = (int)xmlfile.length();
		strBuffer = new char[flen];
		in.read(strBuffer, 0, flen);
		} catch (FileNotFoundException e) {
		e.printStackTrace();
		} catch (IOException e) {
		e.printStackTrace();
		}
		xmlString = new String(strBuffer); //构建String时，可用char[]类型，

		return xmlString;
		}
	
	public String getSubUtilSimple(String soap,String rgex){
		Pattern pattern = Pattern.compile(rgex);// 匹配的模式
		Matcher m = pattern.matcher(soap);
		String result = "";
		ArrayList<String> resultArr = new ArrayList<>();
		while (m.find()) {
			resultArr.add(m.group(1));
		}
		if (resultArr != null && resultArr.size()>0) {
			for (String str : resultArr) {
				result += str + ",";
			}
			result = result.substring(0, result.length()-1);
		}
		return result;
	}

}
